package com.tca.spring.framework.learning.aop.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @author zhoua
 * @Date 2021/5/3
 *
 * 切点表达式
 *
 * 定义切面类
 *   1.通知方法:
 *      前置通知 【@Before】
 *      后置通知 【@After】
 *      返回通知 【@AfterReturning】
 *      异常通知 【@AfterThrowing】
 *      环绕通知 【@Around】
 *          动态代理, 手动推动方法运行【joinPoint.proceed】
 *   2.定义切入的目标方法
 *   3.使用@Aspect 标明当前类是切面类
 */
@Component
@Aspect
@Slf4j
public class LogAspect {

    private static final String POINT_CUT =
            "execution(public void com.tca.spring.framework.learning.aop.service.LogService.*(..))";

    @Pointcut(value = POINT_CUT)
    private void pointCut() {}


    @Before(value = "pointCut()")
    public void logBefore(JoinPoint joinPoint) {
        log.info("logBefore 执行");
    }

    @After(value = "pointCut()")
    public void logAfter(JoinPoint joinPoint) {
        log.info("logAfter 执行");
    }


    @AfterReturning(value = "pointCut()")
    public void afterReturning() {
        log.info("afterReturning 执行");
    }


//    @Around(value = "pointCut()")
//    public Object logAround(ProceedingJoinPoint proceedingJoinPoint) {
//        try {
//            log.info("logAround 执行");
//            Object result = proceedingJoinPoint.proceed();
//            return result;
//        } catch (Throwable throwable) {
//            throwable.printStackTrace();
//        }
//        return null;
//    }


    @AfterThrowing(value = "pointCut()")
    public void afterThrowing() {
        log.info("afterThrowing 执行");
    }

}
